package com.wsjc.common.core.id.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wsjc.common.core.config.JedisConfig;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * TODO ...  无注释
 */
public class IdGeneratorUtil {

	static final Logger logger = LoggerFactory.getLogger(IdGeneratorUtil.class);

	/** 默认缓存时间 */
	private  final int DEFAULT_CACHE_SECONDS = 60 * 60 * 1;// 单位秒 设置成一个钟

	private static JedisPool jedisPool ;
	
	private static JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
	
	static {
		
//		<!-- 最大连接数 -->
		jedisPoolConfig.setMaxTotal(Integer.valueOf(JedisConfig.readConfig("jedis.config.maxTotal")));
//		<!-- 最大空闲连接数 -->
		jedisPoolConfig.setMaxIdle(Integer.valueOf(JedisConfig.readConfig("jedis.config.maxIdle")));
//		<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
		jedisPoolConfig.setMaxWaitMillis(Integer.valueOf(JedisConfig.readConfig("jedis.config.maxWaitMillis")));
//		<!-- 连接最小空闲时间 -->
		jedisPoolConfig.setMinEvictableIdleTimeMillis(Integer.valueOf(JedisConfig.readConfig("jedis.config.minEvictableIdleTimeMillis")));
//		<!-- 每次释放连接的最大数目 -->
		jedisPoolConfig.setNumTestsPerEvictionRun(Integer.valueOf(JedisConfig.readConfig("jedis.config.numTestsPerEvictionRun")));
//		<!-- 释放连接的扫描间隔（毫秒） -->
		jedisPoolConfig.setTimeBetweenEvictionRunsMillis(Long.valueOf(JedisConfig.readConfig("jedis.config.numTestsPerEvictionRun")));
//		<!-- 连接最小空闲时间 --> -->
		jedisPoolConfig.setMinEvictableIdleTimeMillis(Long.valueOf(JedisConfig.readConfig("jedis.config.timeBetweenEvictionRunsMillis")));
//		<!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
		jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(Long.valueOf(JedisConfig.readConfig("jedis.config.softMinEvictableIdleTimeMillis")));
//		<!-- 在获取连接的时候检查有效性, 默认false -->
		jedisPoolConfig.setTestOnReturn(Boolean.valueOf(JedisConfig.readConfig("jedis.config.testOnBorrow")));
//		<!-- 在空闲时检查有效性, 默认false -->
		jedisPoolConfig.setTestWhileIdle(Boolean.valueOf(JedisConfig.readConfig("jedis.config.testWhileIdle")));
//		<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
		jedisPoolConfig.setBlockWhenExhausted(Boolean.valueOf(JedisConfig.readConfig("jedis.config.blockWhenExhausted")));


	}
	
	public IdGeneratorUtil(String host, int port) {
		 jedisPool = new JedisPool(jedisPoolConfig, host, port, 100000, JedisConfig.readConfig("redis.auth.password"));
	}
	

	/**
	 * 释放redis资源
	 * @param jedis
	 */
	private  void releaseResource(Jedis jedis) {
		if (jedis != null) {
			jedis.close();
//			jedisSentinelPool.destroy(); 
//			jedisSentinelPool.returnResource(jedis);
		}
	}

	/**
	 * 删除Redis中的所有key
	 * 
	 * @param jedis
	 * @throws Exception
	 */
	public  void flushAll(Object key) {
		
		Jedis jedis = jedisPool.getResource();
		
		try {
			jedis.flushAll();
		} catch (Exception e) {
			logger.error("Cache清空失败：" , e);
		} finally {
			releaseResource(jedis);
		}
	}

	/**
	 * 保存一个对象到Redis中(缓存过期时间:使用此工具类中的默认时间) . <br/>
	 * 
	 * @param key
	 *            键 . <br/>
	 * @param object
	 *            缓存对象 . <br/>
	 * @return true or false . <br/>
	 * @throws Exception
	 */
	public  Boolean save(String key, String object) {
		return save(key, object, DEFAULT_CACHE_SECONDS);
	}

	/**
	 * 保存一个对象到redis中并指定过期时间
	 * 
	 * @param key
	 *            键 . <br/>
	 * @param object
	 *            缓存对象 . <br/>
	 * @param seconds
	 *            过期时间（单位为秒）.<br/>
	 * @return true or false .
	 */
	public  Boolean save(String key, String value, int seconds) {
		
		Jedis jedis = jedisPool.getResource();
		
		try {
			jedis.set(key, value);
			// = -1 不设置有效期，永久有效
			if(seconds != -1){
  			   jedis.expire(key, seconds);
			}
			return true;
		} catch (Exception e) {
			logger.error("Cache保存失败：", e);
			return false;
		} finally {
			releaseResource(jedis);
		}
	}

	/**
	 * 根据缓存键获取Redis缓存中的值.<br/>
	 * 
	 * @param key
	 *            键.<br/>
	 * @return Object .<br/>
	 * @throws Exception
	 */
	public  Object get(String key) {
		
		Jedis jedis = jedisPool.getResource();
		
		try {
			String obj = jedis.get(key);
			return obj == null ? null : obj;
		} catch (Exception e) {
			logger.error("Cache获取失败：" , e);
			return null;
		} finally {
			releaseResource(jedis);
		}
	}

	/**
	 * 根据缓存键清除Redis缓存中的值.<br/>
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public  Boolean del(String key) {
		
		Jedis jedis = jedisPool.getResource();
		
		try {
			jedis.del(key);
			return true;
		} catch (Exception e) {
			logger.error("Cache删除失败：" , e);
			return false;
		} finally {
			releaseResource(jedis);
		}
	}


	/**
	 * 
	 * @param key
	 * @param seconds
	 *            超时时间（单位为秒）
	 * @return
	 */
	public  Boolean expire(String key, int seconds) {

		Jedis jedis = jedisPool.getResource();
		try {
			jedis.expire(key, seconds);
			return true;
		} catch (Exception e) {
			logger.error("Cache设置超时时间失败：" , e);
			return false;
		} finally {
			releaseResource(jedis);
		}
	}



	/**
	 * 判断一个key是否存在
	 * 
	 * @param key
	 * @return
	 */
	public  Boolean exists(String key) {
		
		Boolean result = false;
		Jedis jedis = jedisPool.getResource();
		
		try {
			result = jedis.exists(key);
			return result;
		} catch (Exception e) {
			logger.error("Cache获取失败：" , e);
			return false;
		} finally {
			releaseResource(jedis);
		}
	}
	
	/**
	 * 获取Redis中的key 的 ttl
	 * 
	 * @param jedis
	 * @throws Exception
	 */
	public  long getTtl(String key ) {
		
		Jedis jedis = jedisPool.getResource();
		
		try {
			return jedis.ttl(key) ;
		} catch (Exception e) {
			logger.error("Cache获取ttl失败：" , e);
		} finally {
			releaseResource(jedis);
		}
		return  0 ;
	}
	
	/**
	 * 获取Incr
	 * 
	 * @param key
	 * @param field
	 * @return
	 */
	public String getIncr(String key) {

		Jedis jedis = jedisPool.getResource();
		
		try {
			String result = String.valueOf(jedis.incr(key));
			return result;
		} catch (Exception e) {
			logger.error("自增1失败 是否存在该值失败：", e);
			return null;
		} finally {
			releaseResource(jedis);
		}
	}
	
	
}
